package com.flow.service.provider.check.role.service.impl;

import com.flow.framework.common.exception.CheckedException;
import com.flow.framework.core.pojo.vo.PageVo;
import com.flow.framework.lock.helper.LockHelper;
import com.flow.framework.persistence.helper.TransactionHelper;
import com.flow.framework.persistence.persistence.page.Page;
import com.flow.framework.persistence.util.PagePoUtil;
import com.flow.service.facade.check.CheckErrorCode;
import com.flow.service.facade.check.role.pojo.vo.RoleModuleVo;
import com.flow.service.provider.check.role.convert.RoleConverter;
import com.flow.service.provider.check.role.pojo.dto.RoleCreateDto;
import com.flow.service.provider.check.role.pojo.dto.RolePageQueryDto;
import com.flow.service.provider.check.role.pojo.po.Role;
import com.flow.service.provider.check.role.pojo.vo.RoleVo;
import com.flow.service.provider.check.enumeration.RoleLockKeyEnum;
import com.flow.service.provider.check.role.persistence.service.IRolePoService;
import com.flow.service.provider.check.role.service.IRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;

/**
 * 角色服务业务服务
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2023/4/16
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class RoleServiceImpl implements IRoleService {

    private final IRolePoService rolePoService;

    /**
     * 根据角色编码获取角色信息
     *
     * @param roleCode roleCode
     * @param allowNull allowNull
     * @return
     */
    @Override
    public RoleModuleVo getRoleByCode(String roleCode, boolean allowNull) {
        Role role = rolePoService.getRoleByCode(roleCode, allowNull);
        return RoleConverter.convertToModuleVo(role);
    }

    /**
     * 创建角色
     *
     * @param dto dto
     * @return
     */
    @Override
    public RoleVo create(RoleCreateDto dto) {
        String roleCode = dto.getRoleCode();
        Role role = RoleConverter.convertToPo(dto);
        LockHelper.voidLockExecute(null, RoleLockKeyEnum.ROLE_CODE_CHECK_LOCK_KEY,
                Collections.singletonList(roleCode),
                () -> {
                    boolean roleCodeExist = rolePoService.isRoleCodeExist(roleCode);
                    if (roleCodeExist) {
                        log.error("role code exist, no : {}", roleCode);
                        throw new CheckedException(CheckErrorCode.ROLE_CODE_EXIST_ERROR);
                    }
                    TransactionHelper.localNewTransactionVoidExec(() -> rolePoService.save(role));
                });
        Role roleInDb = rolePoService.getById(role.getId(), false);
        return RoleConverter.convertToVo(roleInDb);
    }

    /**
     * 分页查询角色
     *
     * @param dto dto
     * @return
     */
    @Override
    public PageVo<RoleVo> page(RolePageQueryDto dto) {
        Page<Role> page = rolePoService.page(dto);
        return PagePoUtil.convertToPageVo(page, RoleConverter::convertToVo);
    }
}